package com.greenyoung.pwiki.elasticsearch.search.controller;

import com.greenyoung.pwiki.common.entity.Result;
import com.greenyoung.pwiki.common.utils.PageUtils;
import com.greenyoung.pwiki.elasticsearch.search.entity.FrontedQuery;
import com.greenyoung.pwiki.elasticsearch.search.entity.Markdown;
import com.greenyoung.pwiki.elasticsearch.search.mapper.MarkdownSearchResultMapper;
import com.greenyoung.pwiki.elasticsearch.search.repository.MarkdownRepository;
import io.swagger.annotations.*;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@Api(tags = "Elasticsearch搜索")
@RequestMapping("/el/search")
public class SearchController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    MarkdownRepository markdownRepository;
    @Autowired
    ElasticsearchRestTemplate elasticsearchTemplate;

    //    @PostMapping("/highlight")
    @GetMapping("/highlight")
    @ApiOperation(value = "关键字高亮搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "keyword", value = "要查找的关键字", paramType = "query", required = true, example = "我"),
            @ApiImplicitParam(name = "type", value = "文档类型", paramType = "query", defaultValue = "md", dataType = "String", example = "md", allowableValues = "md,pdf")
    }
    )
    public Result search(@RequestParam String keyword, @RequestParam String type) {

//        String type = (String) params.get("type");
//        String keyword = (String) params.get("keyword");
        switch (type.toLowerCase()) {
            case "md":
                //设置高亮字段
                HighlightBuilder highlightBuilder = new HighlightBuilder();
                highlightBuilder.field("attachment.content");

                //排除一些不需要的字段，全文内容太长，排除，url没有返回给客户端的必要，排除
                FetchSourceFilterBuilder fetchSourceFilterBuilder = new FetchSourceFilterBuilder().withExcludes("attachment.content", "url");

                //设置分页
                Pageable pageable = PageRequest.of(0, 2);

                NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
                        .withHighlightBuilder(highlightBuilder)
                        .withSourceFilter(fetchSourceFilterBuilder.build())
                        .withQuery(QueryBuilders.multiMatchQuery(keyword, "attachment.content"))
                        //查询第0页的数据，每页大小是2
                        .withPageable(pageable);
//                queryBuilder.withQuery(QueryBuilders.matchQuery("name", "我"));

//                SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

                Page<Markdown> sampleEntities = elasticsearchTemplate.queryForPage(queryBuilder.build(), Markdown.class, new MarkdownSearchResultMapper());

                for (Markdown markdown : sampleEntities) {
                    logger.info(markdown.toString());
                }

                //返回数据中的highlight不属于markdown中字段
//                Page<Markdown> markdownPage = markdownRepository.search(queryBuilder.build());
//
//                long total = markdownPage.getTotalElements();
//                logger.info("total=" + total);
//
//                for (Markdown markdown : markdownPage) {
//                    logger.info(markdown.toString());
//                }
                PageUtils page = new PageUtils(pageable);
                page.setList(sampleEntities.toList());
                page.setTotalPage(sampleEntities.getTotalPages());
                page.setTotalCount((int) sampleEntities.getTotalElements());

                return Result.ok().put("page", page);
            case "pdf":
                break;
            default:
                return Result.error("文档类型不识别");
        }
        return Result.error();
    }

    /**
     * 返回指定id的所有文本数据
     * TODO：处理超大文本
     *
     * @return
     */
    @GetMapping("/content")
    @ApiOperation(value = "获取全文内容")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要获取的文本id", paramType = "query", required = true, example = "1340426195828768")
    } )
    public Result getFileContent(@RequestParam Map<String, String> param) {
        Long id = Long.valueOf(param.get("id"));

        Optional<Markdown> optional = markdownRepository.findById(id);
        if (optional.isPresent()) {
            Markdown markdown = optional.get();

            String info =
                    String.format("[*] 从el获取到%s(%d)的文本内容", markdown.getName(), markdown.getId());
            logger.info(info);
            logger.debug(markdown.toString());

            return Result.ok().put("content", markdown.getAttachment().getContent());
        }

        return Result.error("获取内容失败，检查id是否正确");
    }


}

